package com.wk.code.wkserver.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.wk.code.wkserver.constant.Constant;
import com.wk.code.wkserver.constant.NumberConstant;
import com.wk.code.wkserver.entity.Role;
import com.wk.code.wkserver.entity.SysUser;
import com.wk.code.wkserver.exception.BizException;
import com.wk.code.wkserver.mapper.RoleMapper;
import com.wk.code.wkserver.mapper.SysUserMapper;
import com.wk.code.wkserver.request.admin.SysUserRequest;
import com.wk.code.wkserver.response.admin.MenuResponse;
import com.wk.code.wkserver.response.admin.SysUserPageResponse;
import com.wk.code.wkserver.response.admin.SysUserResponse;
import com.wk.code.wkserver.response.admin.UserInfoResponse;
import com.wk.code.wkserver.response.base.PageInfo;
import com.wk.code.wkserver.service.IPermissionService;
import com.wk.code.wkserver.service.IRoleService;
import com.wk.code.wkserver.service.ISysUserService;
import com.wk.code.wkserver.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 运营后台用户表 服务实现类
 * </p>
 *
 * @author wq
 * @since 2021-07-19
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private TokenUtils tokenUtils;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private IRoleService roleService;

    @Resource
    private IPermissionService permissionService;

    @Resource
    private HttpServletRequest request;


    @Override
    public SysUserResponse login(SysUserRequest request) {
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().
                eq(SysUser::getMobile, request.getMobile()));
        if (Objects.isNull(sysUser)) {
            throw new BizException("你还未注册哦");
        }
        if (!PasswordUtils.matches(sysUser.getSalt(), request.getPassword(), sysUser.getPassword())) {
            throw new BizException("请输入正确的账号密码哦");
        }
        //创建令牌
        String token = createToken(sysUser);
        SysUserResponse response = new SysUserResponse();
        response.setToken(token);
        UserInfoResponse infoResponse = new UserInfoResponse();
        infoResponse.setUserId(sysUser.getId());
        infoResponse.setNickname(sysUser.getNickname());
        infoResponse.setAvatar(sysUser.getAvatar());
        response.setUserInfoResponse(infoResponse);
        Role role = roleMapper.selectById(sysUser.getRoleId());
        if (Objects.nonNull(role)) {
            infoResponse.setRoleName(role.getName());
        }
        List<MenuResponse> menus = permissionService.findMenus(sysUser.getRoleId());
        response.setMenuList(menus);
        return response;
    }

    @Override
    public PageInfo<SysUserPageResponse> page(SysUserRequest request) {
        IPage<SysUser> page = new Page<>(request.getPageNumber(), request.getPageSize());
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(request.getNickname())) {
            wrapper.like(SysUser::getNickname, request.getNickname());
        }
        wrapper.orderByDesc(SysUser::getCreateTime);
        List<SysUser> records = baseMapper.selectPage(page, wrapper).getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            List<SysUserPageResponse> list = records.stream().map(x -> {
                SysUserPageResponse response = new SysUserPageResponse();
                BeanUtils.copyProperties(x, response);
                Role role = roleMapper.selectById(x.getRoleId());
                if (Objects.nonNull(role)) {
                    response.setRoleName(role.getName());
                }
                return response;
            }).collect(Collectors.toList());
            return new PageInfo<>(page.getTotal(), list);
        }
        return null;
    }

    @Override
    public void updateSysUser(SysUserRequest request) {

    }

    @Override
    public void logout() {
        tokenUtils.logout(request);
    }

    @Override
    public void register(SysUserRequest request) {
        if (StringUtils.isEmpty(request.getMobile())) {
            throw new BizException("请输入手机号");
        }
        if (StringUtils.isEmpty(request.getPassword())) {
            throw new BizException("请输入密码");
        }

        if (StringUtils.isEmpty(request.getNickname())) {
            throw new BizException("请输入昵称");
        }
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().
                eq(SysUser::getMobile, request.getMobile()));
        if (Objects.nonNull(sysUser)) {
            throw new BizException("该账号已注册");
        }
        SysUser user = new SysUser();
        user.setMobile(request.getMobile());
        user.setAvatar(Constant.DEFAULT_AVATAR);
        user.setPassword(request.getPassword());
        user.setRoleId(1);
        user.setNickname(request.getNickname());
        save(user);
    }

    @Override
    public void addUser(SysUserRequest req) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(req, sysUser);
        String salt = PasswordUtils.getSalt();
        sysUser.setSalt(salt);
        sysUser.setPassword(PasswordUtils.encode(req.getPassword(), salt));
        sysUser.setAvatar(Constant.DEFAULT_AVATAR);
        save(sysUser);
    }

    @Override
    public SysUser randCustomer() {
        return baseMapper.randCustomer();
    }

    @Override
    public SysUser selectAdminUser() {
        return baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().
                eq(SysUser::getRoleId, NumberConstant.ONE_THOUSAND));
    }

    @Override
    public String selectUserRole(Integer sysUserId) {
        SysUser sysUser = baseMapper.selectById(sysUserId);
        if (Objects.nonNull(sysUser)) {
            //获取角色ID
            return roleService.selectRoleName(sysUser.getRoleId());
        }
        return null;
    }

    @Override
    public SysUser selectUserId(String mobile) {
        return baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getMobile, mobile));
    }

    /**
     * 创建令牌
     *
     * @param sysUser 系统用户
     * @return 令牌
     */
    private String createToken(SysUser sysUser) {
        //设置半个小时
        long expireTime = GeneratorUtil.generateExpireTime(Constant.CONST_ONE_DAY);
        //登录成功创建令牌
        String token = JwtUtil.createSysUserToken(sysUser, expireTime);
        redisUtils.hset(Constant.ADMIN_USER_TOKEN_MAP, sysUser.getId().toString(), "" + expireTime);
        return token;
    }
}
